package com.yanfan.framework.aspectj;

import com.yanfan.common.annotation.CacheBatch;
import com.yanfan.common.annotation.CacheBatchEvict;
import com.yanfan.framework.utils.CacheBatchAnnotationUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 示例：
 *  @CacheBatch(batchEvict = {
 *      @CacheBatchEvict(cacheNames = "device", key = "'selectProductAuthenticate_*_' + #product.productId")
 *      @CacheBatchEvict(cacheNames = "device", key = "'selectProductAuthenticate1_*_' + #product.productId")
 *  })
 * @description:
 * @author: lsy
 * @date: 2024年12月22日 23:55:41
 */
@Slf4j
@Aspect
@Component
public class CacheBatchAspect {

    /**
     * 定义切入点
     */
    @Pointcut("@annotation(com.yanfan.common.annotation.CacheBatch)")
    public void pointcut() {

    }

    @Around("pointcut()")
    public Object proceed(ProceedingJoinPoint joinPoint) throws Throwable {
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        Object[] args = joinPoint.getArgs();
        // 1.获取注解参数值 SpEL表达式
        CacheBatch cacheBatch = method.getAnnotation(CacheBatch.class);
        CacheBatchEvict[] cacheBatchEvicts = cacheBatch.batchEvict();
        for (CacheBatchEvict cacheBatchEvict : cacheBatchEvicts) {
            CacheBatchAnnotationUtils.cacheBatchEvict(method, args, cacheBatchEvict);
        }

        // 4.执行目标方法
        return joinPoint.proceed();
    }
}
